package cn.elwy.rcp.ui.table.listener;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.eclipse.swt.widgets.Display;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.elwy.rcp.ui.table.event.EventManager;

public abstract class PropertyListener implements PropertyChangeListener {

  private Logger logger = LoggerFactory.getLogger(this.getClass());
  protected Map<String, String> propertyNameMap;

  public PropertyListener() {
    propertyNameMap = new HashMap<String, String>();
  }

  @Override
  public void propertyChange(PropertyChangeEvent evt) {
    if (evt.getPropertyName() == null) {
      return;
    }
    final String methodName = propertyNameMap.get(evt.getPropertyName());
    final Object obj = this;
    final Object oldValue = evt.getOldValue();
    final Object newValue = evt.getNewValue();
    Display.getDefault().syncExec(new Runnable() {

      @Override
      public void run() {
        try {
          Class<?> clazz = obj.getClass();
          Method method = clazz.getMethod(methodName, Object.class, Object.class);
          if (method.getParameterTypes().length != 2) {
            logger.warn(clazz + " 中未找到方法：" + methodName);
            return;
          }
          method.setAccessible(true);
          method.invoke(obj, oldValue, newValue);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }

  public void registListener() {
    regist();
  }

  private void regist() {
    initPropertyNameMap(propertyNameMap);
    if (propertyNameMap.isEmpty()) {
      return;
    }
    Set<String> propertieNameSet = propertyNameMap.keySet();
    String[] propertieNames = new String[propertieNameSet.size()];
    propertieNameSet.toArray(propertieNames);
    EventManager.registListener(this, propertieNames);
    registOtherListener();
  }

  protected void registOtherListener() {
  }

  public void unregistListener() {
    EventManager.unregistListener(this);
  }

  /**
   * <pre>
   * KEY: 事件名
   * VALUE: 方法名
   * 
   * 事件名定义如下：
   * propertyMap.put("amc","amc1");
   * propertyMap.put("baidu","baidu1");
   * 
   * 每添加一个事件名，就要定义如下方法：
   * public void amc1(Object oldValue, Object newValue){
   * }
   * public void baidu1(Object oldValue, Object newValue){
   * }
   * </pre>
   */
  public abstract void initPropertyNameMap(Map<String, String> propertyMap);

}
